using System;
using System.Collections;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI;
using System.Drawing;
using Microsoft.SharePoint;
using net.windward.api.csharp;
using System.IO;
using System.Data.Common;
using DevExpress.Web.ASPxEditors;
using DevExpress.Web.ASPxMenu;
using DevExpress.Web.ASPxGridView;
using DevExpress.Web.ASPxTabControl;
using Microsoft.SharePoint.WebControls;
using net.windward.tags;
using net.windward.utils.ado;
using System.Data;
using System.Xml;
using net.windward.util;
using DevExpress.Data;
using log4net;
using log4net.Core;
using System.Text.RegularExpressions;
using System.Web.UI.HtmlControls;
using WindwardArrow.net.windward.arrow.datasource.ado;
using WindwardArrow.net.windward.arrow.datasource.xml;
using WindwardArrow.net.windward.arrow.datasource;
using WindwardArrow.net.windward.arrow;
using WindwardArrow.net.windward.arrow.schedule;
using WindwardArrow.net.windward.arrow.tools;
using System.Collections.Generic;

namespace ArrowWebParts
{
    public class ReportDefinitionWebPart : WebPart
    {
        #region fields

        /// <summary>
        /// overview step 0
        /// </summary>
        private const int STEP_OVERVIEW = 0;
        /// <summary>
        /// template selection step 1
        /// </summary>
        private const int STEP_TEMPLATE_SELECTION = 1;
        /// <summary>
        /// datasource selection step 2
        /// </summary>
        private const int STEP_DATASOURCE_SELECTION = 2;
        /// <summary>
        /// parameter definition step 3
        /// </summary>
        private const int STEP_PARAMETER_DEFINITION = 3;
        /// <summary>
        /// review step 4
        /// </summary>
        private const int STEP_REVIEW = 4;

        private Wizard wizzy;

        private Label[] dataSourceSpecLabelArray;
        private DropDownList[] dataSourceSpecSiteDropDownListArray;
        private DropDownList[] dataSourceSpecLibraryDropDownListArray;
        private DropDownList[] dataSourceSpecFolderDropDownListArray;
        private DropDownList[] dataSourceSpecFileDropDownListArray;

        private Label[] variableNameLabelArray;
        private CheckBox[] variableRequiredCheckBoxArray;
        private CheckBox[] variableHiddenCheckBoxArray;
        private DropDownList[] variableTypeDropDownListArray;
        private TextBox[] variableDescriptionTextBoxArray;

        private TextBox[] variableDefaultValueTextBoxArray;

        // SELECT TYPE PARAMETER
        private TextBox[] variableDataNameTextBoxArray;
        private TextBox[] variableCountTextBoxArray;
        private TextBox[] variableAllTextBoxArray;
        private TextBox[] variableValueTextBoxArray;
        private Label[] variableDataNameLiteralControlArray;
        private Label[] variableCountLabelLiteralControlArray;
        private Label[] variableAllLabelLiteralControlArray;
        private Label[] variableValueLabelLiteralControlArray;

        private Label finalStatusLabel;

        // review step labels
        ASPxLabel assemblyName_val;
        ASPxLabel description_val;
        ASPxLabel templateFilename_val;
        ASPxLabel saveLocation_val;

        //Step 1 Tab
        private ASPxTextBox titleTextbox;
        private ASPxMemo descriptionTextbox;
        private ASPxLabel DocLibSelection;
        private ASPxLabel four;
        private ASPxLabel errorMessageLabel;
        private ASPxLabel errorMessageLabel2;
        const int MAX_NUMBER_DATASOURCES = 20;
        const int MAX_NUMBER_VARIABLES = 20;

        static string imageDir2 = "_layouts/1033/images/arrow/";

        string overviewImage = imageDir2 + "overviewStepAssemble.png";
        string variableImage = imageDir2 + "dataStep.png";
        string reviewImage = imageDir2 + "reviewStep_final.png";
        string assemblyImage = imageDir2 + "assembleStep.png";
        string datasourceImage = imageDir2 + "datasourceStep.png";

        /// <summary>
        /// folderOutGUID key name. ViewState property contains a GUID string.
        /// </summary>
        private static readonly string VS_OUT_FOLDR_GUID = "folderOutGUID";
        /// <summary>
        /// OutputDocLibGUID key name. ViewState property contains a GUID string.
        /// </summary>
        private static readonly string VS_OUT_DOC_LIB_GUID = "OutputDocLibGUID";
        /// <summary>
        /// OutputSiteGUID key name.  ViewState property contains a GUID string.
        /// </summary>
        private static readonly string VS_OUT_SITE_GUID = "OutputSiteGUID";
        /// <summary>
        /// OutputDestination key name. ViewState property contains a string.
        /// </summary>
        private static readonly string VS_OUT_DEST = "OutputDestination";
        /// <summary>
        /// TemplateSiteGUID key name.
        /// </summary>
        private static readonly string VS_TEMPL_SITE_GUID = "TemplateSiteGUID";
        /// <summary>
        /// TemplateDocLibGUID key name.
        /// </summary>
        private static readonly string VS_TEMPL_DOC_LIB_GUID = "TemplateDocLibGUID";
        /// <summary>
        /// TemplateName key name.
        /// </summary>
        private static readonly string VS_TEMPL_NAME = "TemplateName";
        /// <summary>
        /// TemplateGUID key name.
        /// </summary>
        private static readonly string VS_TEMPL_GUID = "TemplateGUID";
        /// <summary>
        /// AssemblyName key name.
        /// </summary>
        private static readonly string VS_RPTDEF_NAME = "AssemblyName";
        /// <summary>
        /// AssemblyDescription key name.
        /// </summary>
        private static readonly string VS_RPTDEF_DESC = "AssemblyDescription";
        /// <summary>
        /// the logger for ReportDefinitionWebPart
        /// </summary>
        private static ILog log = LogManager.GetLogger(typeof(ReportDefinitionWebPart));
        /// <summary>
        /// the file selector control
        /// </summary>
        private SPFileSelector templateFileSelector;
        /// <summary>
        /// the folder selector control
        /// </summary>
        private SPFileSelector outputFolderSelector;

        #endregion

        //Embed some javascript for Handling Events Client side, filtering only the ones that need a postback
        private const string filterIncludeScriptKey = "myFilterIncludeScript";
        private const string EmbeddedScriptFormat_itemClick =
            "<script type='text/javascript'>\n" +
            "  function itemClickFilter(s, e){ \n" +
            "    e.processOnServer = \n" + 
            "      (e.item.GetImageUrl().indexOf('itdl.gif') != -1) || \n" + 
            "      (e.item.GetImageUrl().indexOf('folder.gif') != -1); \n" +
            "  } \n" +
            "</script>\n";
        //private const string filterIncludeScriptKey2 = "myFilterIncludeScript2";
        //private const string EmbeddedScriptFormat_buttonClick =
            //"<script type='text/javascript'>" +
            //" function onButtonClick(s, e)" +
            //"{" +
            //"ASPxClientButton sender = (ASPxClientButton)s;" +
            //"ViewState[\"OutputFormat\"] = sender.ID;" +
            //"}" +
            //"</script>";

        public ReportDefinitionWebPart(){                                                        
            this.PreRender += new EventHandler(WebPart_ClientScript_PreRender);          
        }                                                                                
        private void WebPart_ClientScript_PreRender(object sender , System.EventArgs e ) 
        {
            if (!Page.IsClientScriptBlockRegistered(filterIncludeScriptKey))
            {
                Page.RegisterClientScriptBlock(filterIncludeScriptKey,
                EmbeddedScriptFormat_itemClick);
                //Page.RegisterClientScriptBlock(filterIncludeScriptKey2,
                //EmbeddedScriptFormat_buttonClick);
            }                                 
        }      

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            // trace log
            if (log.IsDebugEnabled)
                log.Debug("Creating child controls");

            try
            {
                // read in license from web.config
                ArrowUtils.InitializeArrow(string.Concat(Page.Request.PhysicalApplicationPath, "\\web.config"));
            }
            catch (LicenseException lex)
            {
                ArrowUtils.LogFatalException(log, lex);
                Controls.Clear();
                Controls.Add(new LiteralControl(string.Format("License Error: {0}", lex.Message)));
                return;
            }

            try
            {

                wizzy = new Wizard();
                wizzy.ID = "RptDefWizzy";
                wizzy.Width = 550;//725;
                wizzy.Height = 400;// 362;
                wizzy.StepStyle.VerticalAlign = VerticalAlign.Top;
                //wizzy.StepStyle.ForeColor = Color.FromArgb(0x5D7B9D);
                //wizzy.BackColor = Color.FromName("SlateBlue");
                wizzy.BorderStyle = BorderStyle.Solid;
                wizzy.BorderColor = Color.FromName("Black");
                wizzy.BorderWidth = 1;
                wizzy.SideBarStyle.Width = 150;
                wizzy.SideBarStyle.VerticalAlign = VerticalAlign.Top;
                //wizzy.SideBarStyle.BackColor = Color.FromArgb(0x7C6F57);
                //wizzy.SideBarButtonStyle.BackColor = Color.FromName("Black");
                wizzy.NextButtonClick += new WizardNavigationEventHandler(wizzy_NextButtonClick);
                wizzy.FinishButtonClick += new WizardNavigationEventHandler(wizzy_FinishButtonClick);
                wizzy.DisplaySideBar = false;

                Button tempButton = (Button)wizzy.FindControl("StepNavigationTemplateContainerID$StepNextButton");
                tempButton.ValidationGroup = "validationGroup" + this.UniqueID;
                tempButton.CausesValidation = true;
                Button tempButton2 = (Button)wizzy.FindControl("StartNavigationTemplateContainerID$StartNextButton");
                tempButton2.ValidationGroup = "validationGroup" + this.UniqueID;
                tempButton2.CausesValidation = true;

                for (int i = 0; i < 5; i++)
                {
                    WizardStepBase newStep = new WizardStep();
                    newStep.ID = "Step" + (i).ToString();
                    newStep.Title = "Step" + (i).ToString();

                    newStep.Controls.Add(createTable(i));

                    wizzy.WizardSteps.Add(newStep);
                }
                Controls.Add(wizzy);
            }
            catch (Exception ex)
            {
                ArrowUtils.LogFatalException(log, ex);
                Controls.Clear();
                Controls.Add(new LiteralControl(string.Format("There was an error creating the report definition web part: {0}", ex.Message)));
                return;
            }

            if (log.IsDebugEnabled)
                log.Debug("Finished creating child controls.");
        }
        private Table createOverviewTab(Style normalStyle, Style normalBoldStyle)
        {
            if (log.IsDebugEnabled)
                log.Debug("Creating overview tab.");

            ASPxLabel s1 = new ASPxLabel();
            ASPxLabel s2 = new ASPxLabel();
            ASPxLabel s3 = new ASPxLabel();
            ASPxLabel s4 = new ASPxLabel();
            s1.ApplyStyle(normalBoldStyle);
            s2.ApplyStyle(normalBoldStyle);
            s3.ApplyStyle(normalBoldStyle);
            s4.ApplyStyle(normalBoldStyle);

            s1.Text = "Step 1:";
            s2.Text = "Step 2:";
            s3.Text = "Step 3:";
            s4.Text = "Finalize\nand\nGo:  ";

            ASPxImage templateStep = new ASPxImage();
            ASPxImage dataStep = new ASPxImage();
            ASPxImage varStep = new ASPxImage();
            ASPxImage reviewStep = new ASPxImage();

            ASPxLabel templateOv = new ASPxLabel();
            ASPxLabel dataOv = new ASPxLabel();
            ASPxLabel varOv = new ASPxLabel();
            ASPxLabel reviewOv = new ASPxLabel();
            templateOv.ApplyStyle(normalStyle);
            dataOv.ApplyStyle(normalStyle);
            varOv.ApplyStyle(normalStyle);
            reviewOv.ApplyStyle(normalStyle);

            templateOv.Width = Unit.Pixel(700);
            dataOv.Width = Unit.Pixel(700);
            varOv.Width = Unit.Pixel(700);
            reviewOv.Width = Unit.Pixel(700);


            templateOv.Text = "Select a template, which can be" +
                              " in the following formats: docx, rtf, xls, xlsx, pptx, and" +
                              " .xml (wordML, spreadsheetML only).";
            dataOv.Text = "Select one or more data definition files to bind to the template.";
            varOv.Text = "Set runtime variables (if necessary).";
            reviewOv.Text = "Review all of the details from each step before generating the report definition.";

            templateStep.ImageUrl = assemblyImage;
            dataStep.ImageUrl = datasourceImage;
            varStep.ImageUrl = variableImage;
            reviewStep.ImageUrl = reviewImage;

            Table overviewTable = createEmptyTable(9, 3, 40, 142);

            overviewTable.Rows[1].Cells[0].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[3].Cells[0].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[5].Cells[0].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[7].Cells[0].VerticalAlign = VerticalAlign.Top;

            overviewTable.Rows[1].Cells[1].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[3].Cells[1].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[5].Cells[1].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[7].Cells[1].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[7].Cells[1].HorizontalAlign = HorizontalAlign.Center;

            overviewTable.Rows[1].Cells[0].Controls.Add(templateStep);
            overviewTable.Rows[3].Cells[0].Controls.Add(dataStep);
            overviewTable.Rows[5].Cells[0].Controls.Add(varStep);
            overviewTable.Rows[7].Cells[0].Controls.Add(reviewStep);

            overviewTable.Rows[1].Cells[1].Controls.Add(s1);
            overviewTable.Rows[3].Cells[1].Controls.Add(s2);
            overviewTable.Rows[5].Cells[1].Controls.Add(s3);
            overviewTable.Rows[7].Cells[1].Controls.Add(s4);

            overviewTable.Rows[1].Cells[2].Controls.Add(templateOv);
            overviewTable.Rows[3].Cells[2].Controls.Add(dataOv);
            overviewTable.Rows[5].Cells[2].Controls.Add(varOv);
            overviewTable.Rows[7].Cells[2].Controls.Add(reviewOv);

            if (log.IsDebugEnabled)
                log.Debug("Finished creating overview tab.");

            return overviewTable;
        }
        /// <summary>
        /// Assembly selection step.
        /// </summary>
        /// <param name="headerStyle"></param>
        /// <param name="normalStyle"></param>
        /// <returns></returns>
        private Table createStep1Tab(Style headerStyle, Style normalStyle)
        {
            if (log.IsDebugEnabled)
                log.Debug("Creating step 1 tab.");

            ASPxLabel step1Header = new ASPxLabel();
            step1Header.Text = "Step 1: Name the report definition file, choose the template, and select the location to save the report definition.";
            step1Header.ApplyStyle(headerStyle);
            step1Header.Width = Unit.Pixel(700);

            ASPxLabel one = new ASPxLabel { Text = "1." };
            one.ApplyStyle(normalStyle);
            ASPxLabel two = new ASPxLabel { Text = "2." };
            two.ApplyStyle(normalStyle);
            ASPxLabel three = new ASPxLabel { Text = "3." };
            three.ApplyStyle(normalStyle);
            four = new ASPxLabel { Text = "4." };
            four.ApplyStyle(normalStyle);

            Style errorStyle = new Style();
            errorStyle.Font.Name = "Verdana";
            errorStyle.Font.Size = FontUnit.Parse("12pt");
            errorStyle.Font.Bold = true;

            errorMessageLabel = new ASPxLabel();
            errorMessageLabel.Text = "";
            errorMessageLabel.ApplyStyle(errorStyle);
            errorMessageLabel.ForeColor = System.Drawing.Color.Red;
            errorMessageLabel.ClientVisible = false;

            ASPxLabel title = new ASPxLabel { Text = "Title of the report definition" };
            ASPxLabel descr = new ASPxLabel { Text = "Description" };
            ASPxLabel reportTempl = new ASPxLabel { Text = " Select a template from the list below" };
            ASPxLabel saveLoc = new ASPxLabel { Text = "Select where you want to save the report definition" };
            ASPxLabel templateLoc = new ASPxLabel
            {
                Text = "Select the template"
            };
            DocLibSelection = new ASPxLabel();

            title.ApplyStyle(normalStyle);
            descr.ApplyStyle(normalStyle);
            reportTempl.ApplyStyle(normalStyle);
            saveLoc.ApplyStyle(normalStyle);
            templateLoc.ApplyStyle(normalStyle);

            titleTextbox = new ASPxTextBox();
            titleTextbox.Width = ArrowUtils.DEFAULT_TXTBX_WIDTH;
            titleTextbox.Text = (string)ViewState[VS_RPTDEF_NAME];

            descriptionTextbox = new ASPxMemo();
            descriptionTextbox.Width = ArrowUtils.DEFAULT_TXTBX_WIDTH;
            descriptionTextbox.Height = new Unit(40, UnitType.Pixel);
            descriptionTextbox.Text = (string)ViewState[VS_RPTDEF_DESC];

            // template file selector
            templateFileSelector = new SPFileSelector(SPFileSelector.Mode.File);

            // output folder selector
            outputFolderSelector = new SPFileSelector(SPFileSelector.Mode.Folder);

            Table t1 = createEmptyTable(8, 3, 41, 125);
            t1.Rows[0].Cells[2].Controls.Add(title);
            t1.Rows[0].Cells[1].Controls.Add(one);
            t1.Rows[1].Cells[2].Controls.Add(titleTextbox);
            t1.Rows[2].Cells[2].Controls.Add(descr);
            t1.Rows[2].Cells[1].Controls.Add(two);
            t1.Rows[3].Cells[2].Controls.Add(descriptionTextbox);
            t1.Rows[4].Cells[2].Controls.Add(templateLoc);
            t1.Rows[4].Cells[1].Controls.Add(three);
            t1.Rows[5].Cells[2].Controls.Add(templateFileSelector);
            t1.Rows[6].Cells[2].Controls.Add(saveLoc);
            t1.Rows[6].Cells[1].Controls.Add(four);
            t1.Rows[7].Cells[2].Controls.Add(outputFolderSelector);

            Table container = createEmptyTable(3, 1, 41, 150);
            container.Rows[0].Cells[0].Controls.Add(step1Header);
            container.Rows[1].Cells[0].Controls.Add(errorMessageLabel);
            container.Rows[1].Cells[0].Height = new Unit(0);
            container.Rows[2].Cells[0].Controls.Add(t1);

            if (log.IsDebugEnabled)
                log.Debug("Finished creating step 1 tab.");

            return container;


        }
        private Table createStep4Tab(Style normalStyle, Style normalBoldStyle)
        {
            if (log.IsDebugEnabled)
                log.Debug("Creating step 4.");

            finalStatusLabel = new Label();

            ASPxLabel assemblyName = new ASPxLabel();
            ASPxLabel description = new ASPxLabel();
            ASPxLabel templateFilename = new ASPxLabel();
            ASPxLabel saveLocation = new ASPxLabel();
            assemblyName.Text = "Report definition filename:";
            description.Text = "Report definition description:";
            templateFilename.Text = "Template filename:";
            saveLocation.Text = "Report definition save location:";

            assemblyName_val = new ASPxLabel();
            description_val = new ASPxLabel();
            templateFilename_val = new ASPxLabel();
            saveLocation_val = new ASPxLabel();
            assemblyName_val.Text = (string)ViewState[VS_RPTDEF_NAME];
            description_val.Text = (string)ViewState[VS_RPTDEF_DESC];
            templateFilename_val.Text = (string)ViewState[VS_TEMPL_NAME];
            saveLocation_val.Text = (string)ViewState[VS_OUT_DEST];

            assemblyName.ApplyStyle(normalBoldStyle);
            description.ApplyStyle(normalBoldStyle);
            templateFilename.ApplyStyle(normalBoldStyle);
            saveLocation.ApplyStyle(normalBoldStyle);
            assemblyName_val.ApplyStyle(normalStyle);
            description_val.ApplyStyle(normalStyle);
            templateFilename_val.ApplyStyle(normalStyle);
            saveLocation_val.ApplyStyle(normalStyle);

            Table t = createEmptyTable(7, 2, 41, 125);
            t.Rows[0].Cells[0].HorizontalAlign = HorizontalAlign.Right;
            t.Rows[1].Cells[0].HorizontalAlign = HorizontalAlign.Right;
            t.Rows[2].Cells[0].HorizontalAlign = HorizontalAlign.Right;
            t.Rows[3].Cells[0].HorizontalAlign = HorizontalAlign.Right;
            t.Rows[4].Cells[0].HorizontalAlign = HorizontalAlign.Right;

            t.Rows[0].Cells[0].Controls.Add(assemblyName);
            t.Rows[1].Cells[0].Controls.Add(description);
            t.Rows[2].Cells[0].Controls.Add(templateFilename);
            t.Rows[3].Cells[0].Controls.Add(saveLocation);
            t.Rows[5].Cells[1].Controls.Add(finalStatusLabel);

            t.Rows[0].Cells[1].HorizontalAlign = HorizontalAlign.Left;
            t.Rows[1].Cells[1].HorizontalAlign = HorizontalAlign.Left;
            t.Rows[2].Cells[1].HorizontalAlign = HorizontalAlign.Left;
            t.Rows[3].Cells[1].HorizontalAlign = HorizontalAlign.Left;
            t.Rows[4].Cells[1].HorizontalAlign = HorizontalAlign.Left;

            t.Rows[0].Cells[1].Controls.Add(assemblyName_val);
            t.Rows[1].Cells[1].Controls.Add(description_val);
            t.Rows[2].Cells[1].Controls.Add(templateFilename_val);
            t.Rows[3].Cells[1].Controls.Add(saveLocation_val);
            //t.Rows[4].Cells[1].Controls.Add(generateButton);

            if (log.IsDebugEnabled)
                log.Debug("Finished creating step 4.");

            return t;
        }
        private SPDocumentLibrary getDocLibObject(string siteGUID, string docLibGUID)
        {
            SPWeb site = ArrowUtils.getSPWeb(siteGUID);
            return (SPDocumentLibrary)site.Lists[new Guid(docLibGUID)];

        }
        private string getAbsPathFromSPFile(SPFile file)
        {
            string relativePath = file.ServerRelativeUrl;
            return SPContext.Current.Site.MakeFullUrl(relativePath);
        }

        #region delegate functions
        /*void generateButton_Click(object o, EventArgs e)
        {
            // reset status
            finalStatusLabel.Text = string.Empty;

            // validate asm name
            string asmName = (string)ViewState[VS_RPTDEF_NAME];
            if (string.IsNullOrEmpty(asmName) || string.IsNullOrEmpty(asmName.Trim()))
            {
                finalStatusLabel.ForeColor = Color.FromName("Red");
                finalStatusLabel.Text = "Error: Title is required and can not be blank.";
                return;
            }
            asmName = asmName.Trim();
            
            // get template file path
            SPDocumentLibrary templateLib = (SPDocumentLibrary)getDocLibObject(
                (string)ViewState[VS_TEMPL_SITE_GUID], (string)ViewState[VS_TEMPL_DOC_LIB_GUID]);
            SPFile templateSPFile = ArrowUtils.GetSPFileFromDocLib(templateLib, (string)ViewState[VS_TEMPL_GUID]);
            string templateAbsolutePath = getAbsPathFromSPFile(templateSPFile);

            // ensure valid asm description
            string asmDesc = (string)ViewState[VS_RPTDEF_DESC];
            asmDesc = asmDesc == null ? string.Empty : asmDesc.Trim();

            //bugbug: don't delete!
            // the following code generates a large string, and is a good candidate for unit testing.
            // we can't put it directly into a method, because it uses globals (not testable).
            // and we can't pass the globals into the method because there's to many (14).
            // what we should do is generate a ReportAssemblyInfo object, and it should have
            // this method that writes it to a string, or perhaps all the way to the file.
            //asm name
            //asm desc
            //template path
            //dataSourceSpecFileDropDownListArray
            //dataSourceSpecLabelArray
            //variableNameLabelArray
            //variableDescriptionTextBoxArray
            //variableRequiredCheckBoxArray
            //variableTypeDropDownListArray
            //variableDefaultValueTextBoxArray
            //variableDataNameTextBoxArray
            //variableCountTextBoxArray
            //variableAllTextBoxArray
            //variableValueTextBoxArray
            
            // begin creating file
            StringBuilder fileContents = new StringBuilder();
            fileContents.AppendFormat("[TITLE]\n{0}\n[DESCRIPTION]\n{1}\n[TEMPLATE]\n{2}", asmName, asmDesc, templateAbsolutePath);
            for (int i = 0; i < dataSourceSpecLibraryDropDownListArray.Length; i++)
            {
                if (dataSourceSpecLabelArray[i].Text.Equals(string.Empty))
                    break;
                String dsName = dataSourceSpecLabelArray[i].Text;
                if (dsName == "(no name)<br/>")
                    dsName = "";
                String dsPath = getDataSourcePath(i);
                fileContents.AppendFormat("\n[DATASOURCENAME]\n{0}\n[DATASOURCEPATH]\n{1}", dsName, dsPath);
            }

            for (int i = 0; i < variableNameLabelArray.Length; i++)
            {
                if (variableNameLabelArray[i].Text.Equals(string.Empty))
                    break;
                fileContents.AppendFormat("\n[VARIABLENAME]\n{0}\n", variableNameLabelArray[i].Text);
                fileContents.AppendFormat("[VARIABLEDESCRIPTION]\n{0}\n", variableDescriptionTextBoxArray[i].Text.Trim());
                fileContents.AppendFormat("[VARIABLEREQUIRED]\n{0}\n", variableRequiredCheckBoxArray[i].Checked.ToString());
                fileContents.AppendFormat("[VARIABLEHIDDEN]\n{0}\n", variableHiddenCheckBoxArray[i].Checked.ToString());
                fileContents.AppendFormat("[VARIABLETYPE]\n{0}\n", variableTypeDropDownListArray[i].SelectedItem.Text);
                fileContents.AppendFormat("[VARIABLEDEFAULT]\n{0}\n", variableDefaultValueTextBoxArray[i].Text.Trim());
                fileContents.AppendFormat("[VARIABLEDATANAME]\n{0}\n", variableDataNameTextBoxArray[i].Text.Trim());
                fileContents.AppendFormat("[VARIABLESELECTCOUNT]\n{0}\n", variableCountTextBoxArray[i].Text.Trim());
                fileContents.AppendFormat("[VARIABLESELECTALLOWED]\n{0}\n", variableAllTextBoxArray[i].Text.Trim());
                fileContents.AppendFormat("[VARIABLESELECTVALUE]\n{0}", variableValueTextBoxArray[i].Text.Trim());
            }

            string asmFilename = string.Format("{0}.reportdef", asmName);
            SPWeb site = SPContext.Current.Web; // in commented block
            ArrowUtils.CreateAndAddFileFromString(fileContents.ToString(), asmFilename, (string)ViewState[VS_OUT_DOC_LIB_GUID], site);

            finalStatusLabel.ForeColor = Color.FromName("Blue");
            finalStatusLabel.Text = "Report Assembly File successfully created.";
        }*/

        void title_ValueChanged(object o, EventArgs e)
        {
            ASPxTextBox sender = (ASPxTextBox)o;
            ViewState[VS_RPTDEF_NAME] = sender.Text.Trim();
        }
        void description_ValueChanged(object o, EventArgs e)
        {
            ASPxMemo sender = (ASPxMemo)o;
            ViewState[VS_RPTDEF_DESC] = sender.Text.Trim();
        }
        public static bool IsGUID(string expression)
        {
            if (expression != null)
            {
                Regex guidRegEx = new Regex(@"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");

                return guidRegEx.IsMatch(expression);
            }
            return false;
        }
        /// <summary>
        /// Returns true if the string is of the form W#GUID, where GUID is a guid string.
        /// </summary>
        /// <param name="sDataItem"></param>
        /// <returns></returns>
        public static bool isWebItem(string sDataItem)
        {
            return sDataItem != null && sDataItem.Length > 2
                && sDataItem.StartsWith("W#") && IsGUID(sDataItem.Substring(2));
        }
        /// <summary>
        /// Returns true if the string is of the form L#GUID, where GUID is a guid string.
        /// </summary>
        /// <param name="sDataItem"></param>
        /// <returns></returns>
        public static bool isDocLibItem(string sDataItem)
        {
            return sDataItem != null && sDataItem.Length > 2
                && sDataItem.StartsWith("L#") && IsGUID(sDataItem.Substring(2));
        }
        /// <summary>
        /// Returns true if the string is of the form F#GUID, where GUID is a guid string.
        /// </summary>
        /// <param name="sDataItem"></param>
        /// <returns></returns>
        public static bool isFolderItem(string sDataItem)
        {
            return sDataItem != null && sDataItem.Length > 2
                && sDataItem.StartsWith("F#") && IsGUID(sDataItem.Substring(2));
        }

        bool step2Validation(out string errorMessage)
        {
            errorMessage = "Error:";
            bool result = true;
            if (dataSourceSpecFileDropDownListArray[0].SelectedValue == null || dataSourceSpecFileDropDownListArray[0].SelectedValue.Length <= 0)
            {
                errorMessage += "*No datasource selected";
                result = false;
            }
            return result;
        }
        /// <summary>
        /// <para>Checks to see if the template has been selected, the report def titled,
        /// and the output destination specified. This always resets the errorMessage string
        /// to "Error:" plus any error messages.</para>
        /// <para>The following template ViewState values must be set.</para>
        /// <para>ViewState[VS_TEMPL_DOC_LIB_GUID]</para>
        /// <para>ViewState[VS_TEMPL_GUID]</para>
        /// <para>ViewState[VS_OUT_DOC_LIB_GUID]</para>
        /// </summary>
        /// <param name="errorMessage"></param>
        /// <returns></returns>
        bool step1Validation(out string errorMessage, SPFileSelectorFolderInfo outFolderInfo)
        {
            errorMessage = "Error:";
            bool result = true;

            // title validation
            if (titleTextbox.Text == null || titleTextbox.Text.Length <= 0)
            {
                result = false;
                errorMessage += " *Title value is not set \n";
            }

            // template validation
            if ((string)ViewState[VS_TEMPL_GUID] == null)
            {
                result = false;
                errorMessage += " *No template has been selected \n";
            }

            // output destination validation
            if (!outFolderInfo.IsSPFolder && !string.IsNullOrEmpty(outFolderInfo.Url))
            {
                result = false;
                errorMessage += " *Invalid save location. The selected directory is a website.";
            }
            else if ((string)ViewState[VS_OUT_DOC_LIB_GUID] == null)
            {
                result = false;
                errorMessage += " *No save location has been selected \n";
            }

            return result;
        }
        void wizzy_NextButtonClick(object o, WizardNavigationEventArgs e)
        {
            // trace log
            if (log.IsDebugEnabled)
                log.Debug("handling next button click");

            /*
             * Should modify the code so it only updates the variables tab when coming from the
             * document selection tab. For now i will update on each tab change, that goes to the variable tab.
             */
            string errorMessage;
            switch (e.CurrentStepIndex)
            {
                case STEP_OVERVIEW:
                    if (log.IsDebugEnabled)
                        log.Debug("moving from overview step");
                    break;
                case STEP_TEMPLATE_SELECTION:
                    if (log.IsDebugEnabled)
                        log.Debug("moving from template selection step");

                    // get template info from file selector
                    SPFileSelectorFileInfo templateFileInfo = templateFileSelector.SelectedFile;
                    if (templateFileInfo.IsAccessDenied)
                    {
                        if (log.IsWarnEnabled)
                            log.WarnFormat("Access denied for template or report definition, {0}.", templateFileInfo.Url);
                        errorMessageLabel.Text = "You do not have permission to access the selected template.";
                        errorMessageLabel.ClientVisible = true;
                        e.Cancel = true;
                        return;
                    }
                    ViewState[VS_TEMPL_NAME] = templateFilename_val.Text = templateFileInfo.Name;
                    ViewState[VS_TEMPL_GUID] = templateFileInfo.Guid;
                    ViewState[VS_TEMPL_DOC_LIB_GUID] = templateFileInfo.LibGuid;
                    ViewState[VS_TEMPL_SITE_GUID] = templateFileInfo.WebGuid;

                    // get output folder info
                    SPFileSelectorFolderInfo outFolderInfo = outputFolderSelector.SelectedFolder;
                    ViewState[VS_OUT_DEST] = saveLocation_val.Text = ArrowUtils.BuildFolderPathDisplayString(outFolderInfo);
                    ViewState[VS_OUT_FOLDR_GUID] = outFolderInfo.Guid;
                    ViewState[VS_OUT_DOC_LIB_GUID] = outFolderInfo.LibGuid;
                    ViewState[VS_OUT_SITE_GUID] = outFolderInfo.WebGuid;

                    errorMessageLabel.ClientVisible = false;
                    if (!step1Validation(out errorMessage, outFolderInfo))
                    {
                        errorMessageLabel.Text = errorMessage;
                        errorMessageLabel.ClientVisible = true;
                        e.Cancel = true;
                        return;
                    }
                    ViewState[VS_RPTDEF_NAME] = assemblyName_val.Text = titleTextbox.Text.Trim();
                    ViewState[VS_RPTDEF_DESC] = description_val.Text = descriptionTextbox.Text.Trim();

                    Stream templateStream = ArrowUtils.GetSPFileStream(new Guid((string)ViewState[VS_TEMPL_SITE_GUID]), new Guid((string)ViewState[VS_TEMPL_GUID]));
                    TemplateMetrics tm = null;
                    try
                    {
                        tm = Report.GetMetrics(templateStream);
                    }
                    catch (Exception ex)
                    {
                        ArrowUtils.LogWarnException(log, ex);
                        errorMessageLabel.Text = string.Format("The template is invalid.\n{0}", ex.Message);
                        errorMessageLabel.ClientVisible = true;
                        e.Cancel = true;
                        return;
                    }
                    string templateExtension = ArrowUtils.getTemplateExtension(templateFileInfo.Name);
                    // this big was written to make sure things like .png files couldn't get by this step
                    //if (string.IsNullOrEmpty(tm.AutoTagData))
                    if (!ArrowUtils.IsTemplateExtension(templateExtension))
                    {
                        errorMessageLabel.Text = string.Format("The template, {0}, is invalid or not configured for use with Arrow.", templateFileInfo.Name);
                        errorMessageLabel.ClientVisible = true;
                        e.Cancel = true;
                        return;
                    }
                    string[] neededDatasources = tm.Datasources;

                    // set their visibility to false
                    for (int i = 0; i < dataSourceSpecLabelArray.Length; i++)
                    {
                        dataSourceSpecLabelArray[i].Visible = false;
                        dataSourceSpecSiteDropDownListArray[i].Visible = false;
                        dataSourceSpecLibraryDropDownListArray[i].Visible = false;
                        dataSourceSpecFolderDropDownListArray[i].Visible = false;
                        dataSourceSpecFileDropDownListArray[i].Visible = false;
                    }

                    string singleDatasource;
                    for (int i = 0; i < neededDatasources.Length; i++)
                    {
                        dataSourceSpecSiteDropDownListArray[i].Items.Clear();
                        dataSourceSpecLibraryDropDownListArray[i].Items.Clear();
                        dataSourceSpecFolderDropDownListArray[i].Items.Clear();
                        dataSourceSpecFileDropDownListArray[i].Items.Clear();

                        dataSourceSpecSiteDropDownListArray[i].Visible = true;
                        dataSourceSpecLibraryDropDownListArray[i].Visible = true;
                        dataSourceSpecFolderDropDownListArray[i].Visible = true;
                        dataSourceSpecFileDropDownListArray[i].Visible = true;
                        dataSourceSpecLabelArray[i].Visible = true;

                        singleDatasource = neededDatasources[i];
                        if (singleDatasource == "")
                            dataSourceSpecLabelArray[i].Text = "(no name)<br/>";
                        else
                            dataSourceSpecLabelArray[i].Text = singleDatasource;

                        // get the current site
                        SPWeb curSite = SPContext.Current.Web; // currently can only read datadef files from same site as webpart

                        // populate the sites
                        SPWebCollection theWebs = ArrowUtils.GetSPWebCollectionFromCurrentSite();
                        foreach (SPWeb web in theWebs)
                        {
                            ListItem webItem = new ListItem(web.Title, web.ID.ToString());
                            if (web.ID == curSite.ID)
                                webItem.Selected = true;
                            dataSourceSpecSiteDropDownListArray[i].Items.Add(webItem);
                        }

                        // populate library lists
                        SPDocumentLibrary library = null;
                        bool isFirstLib = true;
                        foreach (SPList list in curSite.Lists)
                        {
                            if (list is SPDocumentLibrary && !list.Hidden)
                            {
                                if (isFirstLib)
                                {
                                    library = (SPDocumentLibrary)list;
                                    isFirstLib = false;
                                }
                                dataSourceSpecLibraryDropDownListArray[i].Items.Add(new ListItem(list.Title, list.ID.ToString()));
                            }
                        }

                        // populate folder lists
                        dataSourceSpecFolderDropDownListArray[i].Items.Add(new ListItem("<None>", ""));
                        if (library != null)
                        {
                            foreach (SPListItem folderItem in library.Folders)
                            {
                                SPFolder folder = folderItem.Folder;
                                if (folder != null)
                                {
                                    dataSourceSpecFolderDropDownListArray[i].Items.Add(new ListItem(folder.Name, folder.UniqueId.ToString()));
                                }
                            }
                        }

                        // populate the file list
                        if (library != null)
                        {
                            SPFolder selFolder = library.RootFolder;

                            // sort the list items
                            ArrayList sortedItems = new ArrayList();
                            foreach (SPFile item in selFolder.Files)
                            {
                                sortedItems.Add(item);
                            }
                            sortedItems.Sort(new ArrowUtils.SPFileComparer());

                            // add the file items
                            foreach (SPFile file in sortedItems)
                            {
                                if (file.Name.EndsWith(".datadef") || file.Name.EndsWith(".wrd"))
                                {
                                    string dataDefName = string.Empty;
                                    if (file.Name.EndsWith(".datadef"))
                                        dataDefName = file.Name.Trim().Substring(0, file.Name.Trim().LastIndexOf(".datadef"));
                                    else
                                        dataDefName = file.Name.Trim().Substring(0, file.Name.Trim().LastIndexOf(".wrd"));
                                    dataSourceSpecFileDropDownListArray[i].Items.Add(new ListItem(dataDefName, file.Item.UniqueId.ToString()));
                                }
                            }
                        }
                    }

                    if (neededDatasources.Length < 1)
                    {
                        bool hasVars = ArrowUtils.GetNeededVarNamesForDisplay(tm, log).Length > 0;

                        if (hasVars)
                        {
                            setupVarTable(tm);
                            wizzy.ActiveStepIndex = STEP_PARAMETER_DEFINITION;
                        }
                        else
                        {
                            // no vars
                            wizzy.ActiveStepIndex = STEP_REVIEW;
                        }
                    }
                    break;
                case STEP_DATASOURCE_SELECTION:
                    if (log.IsDebugEnabled)
                        log.Debug("moving from datasource selection step");

                    // initialize the error message label invisible
                    errorMessageLabel2.ClientVisible = false;

                    // check if a valid datasource selection has been made
                    if (!step2Validation(out errorMessage))
                    {
                        // invalid datasource selection; message and cancel
                        errorMessageLabel2.Text = "Error: No datasource selected";//bugbug
                        errorMessageLabel2.ClientVisible = true;
                        e.Cancel = true;
                        return;
                    }

                    // get the template metrics
                    Stream templateStream2 = ArrowUtils.GetSPFileStream(new Guid((string)ViewState[VS_TEMPL_SITE_GUID]), new Guid((string)ViewState[VS_TEMPL_GUID]));
                    TemplateMetrics tm2 = Report.GetMetrics(templateStream2);
                  
                    // check if the template has variables; skip to review if none
                    if (ArrowUtils.GetNeededVarNamesForDisplay(tm2, log).Length <= 0)
                    {
                        // no vars, go to review step
                        wizzy.ActiveStepIndex = STEP_REVIEW;
                        return;
                    }

                    setupVarTable(tm2);
                    break;
                case STEP_PARAMETER_DEFINITION:

                    break;
                case STEP_REVIEW:

                    break;
                default:
                    break;
            }
        }
        /// <summary>
        /// Determines if vars are needed, and if so, sets up the var table so that vars can be entered.
        /// </summary>
        /// <param name="tm2"></param>
        private void setupVarTable(TemplateMetrics tm2)
        {
            // get template var list and doc global
            TemplateMetrics tm = ArrowUtils.GetTemplateMetrics(new Guid((string)ViewState[VS_TEMPL_SITE_GUID]), new Guid((string)ViewState[VS_TEMPL_GUID]));
            IList<TemplateVariable> displayVars = ArrowUtils.GetTemplateVarsForDisplay(tm, log);
            bool variablesDefined = displayVars.Count > 0;

            // initialize the parm def forms
            for (int i = displayVars.Count; i < variableNameLabelArray.Length; i++)
            {
                //bugbug - setting values on object[i], but then setting object[i] = null
                // setting object null should be enough then
                hideParmDefControls(i);
                variableNameLabelArray[i].Text = "";
                nullifyParmDefControls(i);
            }

            // unhide a parm def form for each needed var
            for (int i = 0; i < displayVars.Count; i++)
            {
                //variableTypeDropDownListArray[i].Items.Clear();

                unhideParmDefForm(i);

                // show the variable name
                variableNameLabelArray[i].Text = displayVars[i].Name;

                // handle any predefined parameters; default values
                if (variablesDefined)
                {
                    try
                    {
                        // note: tVars indecies match up with neededVars list
                        TemplateVariable varPredef = displayVars[i];
                        variableRequiredCheckBoxArray[i].Checked = varPredef.Required;
                        setParmTypeControl(i, varPredef);
                        if (varPredef.DefaultValues.Length == 0)
                            variableDefaultValueTextBoxArray[i].Text = "";//bugbug
                        else
                            variableDefaultValueTextBoxArray[i].Text = (string)varPredef.DefaultValues[0].Value;

                        variableDescriptionTextBoxArray[i].Text = varPredef.Description;
                    }
                    catch
                    {
                        //bugbug: 2/20/2010; nothing in the catch all, why?
                        if (log.IsWarnEnabled)
                            log.Warn("caught unknown exception while unhiding needed var forms");
                    }
                }
            }
        }

        /// <summary>
        /// Sets the parameter type fields for the specified parameter definition form using the values of
        /// the specified TemplateVar.
        /// </summary>
        /// <param name="i">the parm def index</param>
        /// <param name="varPredef">the TemplateVar</param>
        private void setParmTypeControl(int i, TemplateVariable varPredef)
        {
            switch (varPredef.VarType)
            {
                case TemplateVariable.VAR_TYPE.CURRENCY:
                    variableTypeDropDownListArray[i].SelectedIndex = 0;
                    break;
                case TemplateVariable.VAR_TYPE.DATE:
                    variableTypeDropDownListArray[i].SelectedIndex = 1;
                    break;
                case TemplateVariable.VAR_TYPE.INTEGER:
                    variableTypeDropDownListArray[i].SelectedIndex = 2;
                    break;
                case TemplateVariable.VAR_TYPE.FLOAT:
                    variableTypeDropDownListArray[i].SelectedIndex = 3;
                    break;
                case TemplateVariable.VAR_TYPE.SELECT:
                    variableTypeDropDownListArray[i].SelectedIndex = 4;

                    variableCountTextBoxArray[i].Text = varPredef.Dataset.SelectCount;
                    variableAllTextBoxArray[i].Text = varPredef.Dataset.Select;
                    variableValueTextBoxArray[i].Text = varPredef.Dataset.SelectCheck;
                    variableDataNameTextBoxArray[i].Text = varPredef.Datasource;
                    break;
                case TemplateVariable.VAR_TYPE.TEXT:
                    variableTypeDropDownListArray[i].SelectedIndex = 5;
                    break;
            }
        }

        /// <summary>
        /// <para>Unides the controls for the specified parameter definition form.</para>
        /// <para>This is intended to be used in a loop that iterates over the parm def forms 
        /// that need to be turned on. Eg:</para>
        /// <para>for (int i = 0; i &lt; numParms; i++)</para>
        /// <para>  unhideParmDefControls(i);</para>
        /// </summary>
        /// <param name="i">index of the parm def form</param>
        private void unhideParmDefForm(int i)
        {
            variableNameLabelArray[i].Visible = true;
            variableRequiredCheckBoxArray[i].Visible = true;
            variableHiddenCheckBoxArray[i].Visible = true;
            variableTypeDropDownListArray[i].Visible = true;
            variableDefaultValueTextBoxArray[i].Visible = true;
            variableDescriptionTextBoxArray[i].Visible = true;

            variableCountTextBoxArray[i].Visible = true;
            variableAllTextBoxArray[i].Visible = true;
            variableValueTextBoxArray[i].Visible = true;
            variableCountLabelLiteralControlArray[i].Visible = true;
            variableAllLabelLiteralControlArray[i].Visible = true;
            variableValueLabelLiteralControlArray[i].Visible = true;
            variableDataNameTextBoxArray[i].Visible = true;
            variableDataNameLiteralControlArray[i].Visible = true;
        }

        /// <summary>
        /// Sets the controls for the specified parameter definition form null
        /// </summary>
        /// <param name="i"></param>
        private void nullifyParmDefControls(int i)
        {
            variableNameLabelArray[i] = null;
            variableRequiredCheckBoxArray[i] = null;
            variableHiddenCheckBoxArray[i] = null;
            variableTypeDropDownListArray[i] = null;
            variableDefaultValueTextBoxArray[i] = null;
            variableDescriptionTextBoxArray[i] = null;
            variableCountTextBoxArray[i] = null;
            variableAllTextBoxArray[i] = null;
            variableValueTextBoxArray[i] = null;
            variableCountLabelLiteralControlArray[i] = null;
            variableAllLabelLiteralControlArray[i] = null;
            variableValueLabelLiteralControlArray[i] = null;
            variableDataNameTextBoxArray[i] = null;
            variableDataNameLiteralControlArray[i] = null;
        }

        /// <summary>
        /// <para>Hides the controls for the specified parameter definition form.</para>
        /// <para>This is intended to be used in a loop that iterates over the parm def forms. Eg:</para>
        /// <para>for (int i = 0; i &lt; numParms; i++)</para>
        /// <para>  hideParmDefControls(i);</para>
        /// </summary>
        /// <param name="i">index of the parm def form</param>
        private void hideParmDefControls(int parmInd)
        {
            variableNameLabelArray[parmInd].Visible = false;
            variableRequiredCheckBoxArray[parmInd].Visible = false;
            variableHiddenCheckBoxArray[parmInd].Visible = false;
            variableTypeDropDownListArray[parmInd].Visible = false;
            variableDefaultValueTextBoxArray[parmInd].Visible = false;
            variableDescriptionTextBoxArray[parmInd].Visible = false;
            variableCountTextBoxArray[parmInd].Visible = false;
            variableAllTextBoxArray[parmInd].Visible = false;
            variableValueTextBoxArray[parmInd].Visible = false;
            variableCountLabelLiteralControlArray[parmInd].Visible = false;
            variableAllLabelLiteralControlArray[parmInd].Visible = false;
            variableValueLabelLiteralControlArray[parmInd].Visible = false;
            variableDataNameTextBoxArray[parmInd].Visible = false;
            variableDataNameLiteralControlArray[parmInd].Visible = false;
        }

        void wizzy_FinishButtonClick(object sender, WizardNavigationEventArgs e)
        {
            if (log.IsDebugEnabled)
                log.Debug("handling finish button click");

            // reset status
            finalStatusLabel.Text = string.Empty;

            // validate asm name
            string asmName = (string)ViewState[VS_RPTDEF_NAME];
            if (string.IsNullOrEmpty(asmName) || string.IsNullOrEmpty(asmName.Trim()))
            {
                finalStatusLabel.ForeColor = Color.FromName("Red");
                finalStatusLabel.Text = "Error: Title is required and can not be blank.";
                return;
            }
            asmName = asmName.Trim();

            // get template file path
            SPDocumentLibrary templateLib = (SPDocumentLibrary)getDocLibObject(
                (string)ViewState[VS_TEMPL_SITE_GUID], (string)ViewState[VS_TEMPL_DOC_LIB_GUID]);
            SPFile templateSPFile = ArrowUtils.GetSPFileFromDocLib(templateLib, (string)ViewState[VS_TEMPL_GUID]);
            string templateAbsolutePath = getAbsPathFromSPFile(templateSPFile);

            // ensure valid asm description
            string asmDesc = (string)ViewState[VS_RPTDEF_DESC];
            asmDesc = asmDesc == null ? string.Empty : asmDesc.Trim();

            //bugbug: don't delete!
            // the following code generates a large string, and is a good candidate for unit testing.
            // we can't put it directly into a method, because it uses globals (not testable).
            // and we can't pass the globals into the method because there's to many (14).
            // what we should do is generate a ReportAssemblyInfo object, and it should have
            // this method that writes it to a string, or perhaps all the way to the file.
            //asm name
            //asm desc
            //template path
            //dataSourceSpecFileDropDownListArray
            //dataSourceSpecLabelArray
            //variableNameLabelArray
            //variableDescriptionTextBoxArray
            //variableRequiredCheckBoxArray
            //variableTypeDropDownListArray
            //variableDefaultValueTextBoxArray
            //variableDataNameTextBoxArray
            //variableCountTextBoxArray
            //variableAllTextBoxArray
            //variableValueTextBoxArray

            // begin creating file
            XmlDocument xDoc = new XmlDocument();
            XmlElement ndRptDef = xDoc.CreateElement("reportdef");
            xDoc.AppendChild(ndRptDef);
            XmlElement ndTitle = xDoc.CreateElement("title");
            ndRptDef.AppendChild(ndTitle);
            ndTitle.InnerText = asmName;
            XmlElement ndDesc = xDoc.CreateElement("description");
            ndRptDef.AppendChild(ndDesc);
            ndDesc.InnerText = asmDesc;
            XmlElement ndTempl = xDoc.CreateElement("template");
            ndRptDef.AppendChild(ndTempl);
            ndTempl.InnerText = templateAbsolutePath;

            for (int i = 0; i < dataSourceSpecLibraryDropDownListArray.Length; i++)
            {
                if (dataSourceSpecLabelArray[i].Text.Equals(string.Empty))
                    break;
                String dsName = dataSourceSpecLabelArray[i].Text;
                if (dsName == "(no name)<br/>")
                    dsName = "";
                String dsPath = getDataSourcePath(i);

                XmlElement ndDataSource = xDoc.CreateElement("dataSource");
                ndRptDef.AppendChild(ndDataSource);
                XmlElement ndDataSourceName = xDoc.CreateElement("dataSourceName");
                ndDataSource.AppendChild(ndDataSourceName);
                ndDataSourceName.InnerText = dsName;
                XmlElement ndDataSourcePath = xDoc.CreateElement("dataSourcePath");
                ndDataSource.AppendChild(ndDataSourcePath);
                ndDataSourcePath.InnerText = dsPath;
            }

            for (int i = 0; i < variableNameLabelArray.Length; i++)
            {
                if (variableNameLabelArray[i].Text.Equals(string.Empty))
                    break;

                XmlElement ndVariable = xDoc.CreateElement("variable");
                ndRptDef.AppendChild(ndVariable);
                XmlElement ndVariableName = xDoc.CreateElement("variableName");
                ndVariable.AppendChild(ndVariableName);
                ndVariableName.InnerText = variableNameLabelArray[i].Text;
                XmlElement ndVariableDesc = xDoc.CreateElement("variableDescription");
                ndVariable.AppendChild(ndVariableDesc);
                ndVariableDesc.InnerText = variableDescriptionTextBoxArray[i].Text.Trim();
                XmlElement ndVariableReq = xDoc.CreateElement("variableRequired");
                ndVariable.AppendChild(ndVariableReq);
                ndVariableReq.InnerText = variableRequiredCheckBoxArray[i].Checked.ToString();
                XmlElement ndVariableHidden = xDoc.CreateElement("variableHidden");
                ndVariable.AppendChild(ndVariableHidden);
                ndVariableHidden.InnerText = variableHiddenCheckBoxArray[i].Checked.ToString();
                XmlElement ndVariableType = xDoc.CreateElement("variableType");
                ndVariable.AppendChild(ndVariableType);
                ndVariableType.InnerText = variableTypeDropDownListArray[i].SelectedItem.Text;
                XmlElement ndVariableDefault = xDoc.CreateElement("variableDefault");
                ndVariable.AppendChild(ndVariableDefault);
                ndVariableDefault.InnerText = variableDefaultValueTextBoxArray[i].Text.Trim();
                XmlElement ndVariableDataName = xDoc.CreateElement("variableDataName");
                ndVariable.AppendChild(ndVariableDataName);
                ndVariableDataName.InnerText = variableDataNameTextBoxArray[i].Text.Trim();
                XmlElement ndVariableSelectCount = xDoc.CreateElement("variableSelectCount");
                ndVariable.AppendChild(ndVariableSelectCount);
                ndVariableSelectCount.InnerText = variableCountTextBoxArray[i].Text.Trim();
                XmlElement ndVariableSelectAll = xDoc.CreateElement("variableSelectAll");
                ndVariable.AppendChild(ndVariableSelectAll);
                ndVariableSelectAll.InnerText = variableAllTextBoxArray[i].Text.Trim();
                XmlElement ndVariableSelectValue = xDoc.CreateElement("variableSelectValue");
                ndVariable.AppendChild(ndVariableSelectValue);
                ndVariableSelectValue.InnerText = variableValueTextBoxArray[i].Text.Trim();
            }

            string sFileContents = string.Format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>{0}", xDoc.OuterXml);
            string asmFilename = string.Format("{0}.reportdef", asmName);
            SPDocumentLibrary docLib = ArrowUtils.getDocLibObject((string)ViewState[VS_OUT_SITE_GUID], (string)ViewState[VS_OUT_DOC_LIB_GUID]);
            SPWeb site = docLib.ParentWeb;
            string outFolderGuid = (string)ViewState[VS_OUT_FOLDR_GUID];
            ArrowUtils.CreateAndAddFileFromString(sFileContents, asmFilename, (string)ViewState[VS_OUT_DOC_LIB_GUID], site, outFolderGuid);

            finalStatusLabel.ForeColor = Color.FromName("Blue");
            finalStatusLabel.Text = "Report definition file successfully created.";

            if (log.IsDebugEnabled)
            {
                log.Debug("finished handling finish button click");
                log.Debug(string.Format("file contents: {0}", sFileContents));
            }
        }

        void dataSourceSpecLibraryDropDownListArray_SelectedIndexChanged(object o, EventArgs e)
        {
            if (log.IsDebugEnabled)
                log.Debug("handling selected datadef lib changed");
            
            // get index of dropdown list in list array; this has to be done to match it
            // up with the correct file list to update.
            int index = -1;
            for (int i = 0; i < dataSourceSpecLibraryDropDownListArray.Length; i++)
            {
                if (o.Equals(dataSourceSpecLibraryDropDownListArray[i]))
                {
                    index = i;
                    break;
                }
            }
            if (index == -1) //bugbug: throw exception?
                return;

            // get the new library
            Guid selSiteID = new Guid(dataSourceSpecSiteDropDownListArray[index].SelectedValue);
            SPWeb site = ArrowUtils.GetSPWebCollectionFromCurrentSite()[selSiteID];
            Guid libraryID = new Guid(dataSourceSpecLibraryDropDownListArray[index].SelectedValue);
            SPDocumentLibrary library = (SPDocumentLibrary)site.Lists[libraryID];

            // populate the folder list
            dataSourceSpecFolderDropDownListArray[index].Items.Clear();
            dataSourceSpecFolderDropDownListArray[index].Items.Add(new ListItem("<None>", ""));
            if (library != null)
            {
                foreach (SPListItem folderItem in library.Folders)
                {
                    SPFolder folder = folderItem.Folder;
                    if (folder != null)
                    {
                        dataSourceSpecFolderDropDownListArray[index].Items.Add(new ListItem(folder.Name, folder.UniqueId.ToString()));
                    }
                }
            }

            // populate the file list
            dataSourceSpecFileDropDownListArray[index].Items.Clear();
            if (library != null)
            {
                SPFolder selFolder = library.RootFolder;

                // sort the list items
                ArrayList sortedItems = new ArrayList();
                foreach (SPFile item in selFolder.Files)
                {
                    sortedItems.Add(item);
                }
                sortedItems.Sort(new ArrowUtils.SPFileComparer());

                // add the file items
                foreach (SPFile file in sortedItems)
                {
                    if (file.Name.EndsWith(".datadef") || file.Name.EndsWith(".wrd"))
                    {
                        string dataDefName = string.Empty;
                        if (file.Name.EndsWith(".datadef"))
                            dataDefName = file.Name.Trim().Substring(0, file.Name.Trim().LastIndexOf(".datadef"));
                        else
                            dataDefName = file.Name.Trim().Substring(0, file.Name.Trim().LastIndexOf(".wrd"));
                        dataSourceSpecFileDropDownListArray[index].Items.Add(new ListItem(dataDefName, file.Item.UniqueId.ToString()));
                    }
                }
            }
        }

        #endregion

        #region delegate helper functions

        private string getDataSourcePath(int num)
        {
            Guid selSiteID = new Guid(dataSourceSpecSiteDropDownListArray[num].SelectedValue);
            SPWeb site = ArrowUtils.GetSPWebCollectionFromCurrentSite()[selSiteID];

            Guid dataSourceLibID = new Guid(dataSourceSpecLibraryDropDownListArray[num].SelectedValue);
            Guid dataSourceID = new Guid(dataSourceSpecFileDropDownListArray[num].SelectedValue);
            SPDocumentLibrary dataSourceLib = (SPDocumentLibrary)site.Lists[dataSourceLibID];
            string sFolderID = dataSourceSpecFolderDropDownListArray[num].SelectedValue;
            SPFolder selFolder = dataSourceLib.RootFolder;
            if (!string.IsNullOrEmpty(sFolderID))
                selFolder = site.GetFolder(new Guid(sFolderID));
            SPFile dataSourceFile = dataSourceLib.Items[dataSourceID].File;
            string dataSourceRelativePath = dataSourceFile.ServerRelativeUrl;
            string dataSourceAbsolutePath = SPContext.Current.Site.MakeFullUrl(dataSourceRelativePath);

            return dataSourceAbsolutePath;
        }

        #endregion

        #region table creation functions

        private Table createTable(int tableNum)
        {
            Style headerStyle = new Style();
            headerStyle.Font.Name = "Verdana";
            headerStyle.Font.Size = FontUnit.Parse("14pt");

            Style normalStyle = new Style();
            normalStyle.Font.Name = "Verdana";
            normalStyle.Font.Size = FontUnit.Parse("10pt");

            Style normalBoldStyle = new Style();
            normalBoldStyle.Font.Name = "Verdana";
            normalBoldStyle.Font.Size = FontUnit.Parse("12pt");
            normalBoldStyle.Font.Bold = true;

            Table t;
            switch (tableNum)
            {
                case 0:
                    t = createOverviewTab(normalStyle, normalBoldStyle);
                    break;
                case 1:
                    t = createStep1Tab(headerStyle, normalStyle);
                    break;
                case 2:
                    t = createTable1(headerStyle);
                    break;
                case 3:
                    t = createTable2(headerStyle);
                    break;
                case 4:
                    t = createStep4Tab(normalStyle, normalBoldStyle);
                    break;
                default:
                    // Never gets here
                    t = createEmptyTable(1, 1, 1, 1);
                    break;
            }

            t.ID = "table" + tableNum;
            t.CellPadding = 10;
            //t.BorderStyle = BorderStyle.Solid;
            //t.BorderColor = Color.FromName("Black");
            //t.BorderWidth = 1;

            return t;
        }
        /*
        private Table createTable0()
        {
            //SPWeb site = SPContext.Current.Web;

            Table t = createEmptyTable(5, 2, 41, 125);

            //0,0
            t.Rows[0].Cells[0].Controls.Add(new LiteralControl("<b>Arrow Report Definition Wizard</b>"));

            //0,1
            t.Rows[0].Cells[1].Controls.Add(new LiteralControl("<u>This wizard helps you create a report definition file to use for generating reports.</u>"));

            //1,0
            t.Rows[1].Cells[0].Controls.Add(new LiteralControl("Title(required):"));

            //1,1
            titleTextBox = new TextBox();
            titleTextBox.ID = "titleTextBox";
            titleTextBox.Width = 225;
            t.Rows[1].Cells[1].Controls.Add(titleTextBox);
            titleTextBoxValidator = new RequiredFieldValidator();
            titleTextBoxValidator.Display = ValidatorDisplay.Dynamic;
            titleTextBoxValidator.ErrorMessage = "* Enter a title";
            titleTextBoxValidator.Text = "* Enter a title";
            titleTextBoxValidator.ControlToValidate = "titleTextBox";
            titleTextBoxValidator.ValidationGroup = "validationGroup" + this.UniqueID;
            t.Rows[1].Cells[1].Controls.Add(titleTextBoxValidator);

            //2,0
            t.Rows[2].Cells[0].Controls.Add(new LiteralControl("Description:"));

            //2,1
            descriptionTextBox = new TextBox();
            descriptionTextBox.ID = "descriptionTextBox";
            descriptionTextBox.Width = 225;
            descriptionTextBox.TextMode = TextBoxMode.MultiLine;
            t.Rows[2].Cells[1].Controls.Add(descriptionTextBox);

            //3,0
            t.Rows[3].Cells[0].Controls.Add(new LiteralControl("Report Template:"));

            //3,1
            // part 1
            t.Rows[3].Cells[1].Controls.Add(new LiteralControl("Site<br/>"));
            templateSiteDropDownList = new DropDownList();
            templateSiteDropDownList.SelectedIndexChanged += new EventHandler(templateSiteDropDownList_SelectedIndexChanged);
            templateSiteDropDownList.AutoPostBack = true;
            SPSite oSiteCollection = SPContext.Current.Site;

            SPWebCollection collWebsite = ArrowUtils.GetSPWebCollectionFromCurrentSite();
            foreach (SPWeb oWebsite in collWebsite)
            {
                templateSiteDropDownList.Items.Add(new ListItem(oWebsite.Title, oWebsite.ID.ToString()));
                oWebsite.Dispose();
            }

            templateSiteDropDownList.SelectedIndex = templateSiteDropDownList.Items.IndexOf(templateSiteDropDownList.Items.FindByValue(SPContext.Current.Web.ID.ToString()));
            t.Rows[3].Cells[1].Controls.Add(templateSiteDropDownList);

            // part 2
            t.Rows[3].Cells[1].Controls.Add(new LiteralControl("<br/><br/>Document Library<br/>"));
            templateLibraryDropDownList = new DropDownList();
            templateLibraryDropDownList.SelectedIndexChanged += new EventHandler(templateLibraryDropDropList_SelectedIndexChanged);
            templateLibraryDropDownList.AutoPostBack = true;
            t.Rows[3].Cells[1].Controls.Add(templateLibraryDropDownList);

            // part 3
            t.Rows[3].Cells[1].Controls.Add(new LiteralControl("<br/><br/>File Name<br/>"));
            templateFileDropDownList = new DropDownList();
            templateFileDropDownList.ID = "templateFileDropDownList";
            t.Rows[3].Cells[1].Controls.Add(templateFileDropDownList);

            templateSiteDropDownList_SelectedIndexChanged(null, null);

            templateFileDropDownListValidator = new RequiredFieldValidator();
            templateFileDropDownListValidator.Display = ValidatorDisplay.Dynamic;
            templateFileDropDownListValidator.ErrorMessage = "* Select a template";
            templateFileDropDownListValidator.Text = "* Select a template";
            templateFileDropDownListValidator.ControlToValidate = "templateFileDropDownList";
            templateFileDropDownListValidator.ValidationGroup = "validationGroup" + this.UniqueID;
            templateFileDropDownListValidator.InitialValue = "";
            t.Rows[3].Cells[1].Controls.Add(templateFileDropDownListValidator);

            //4,0
            t.Rows[4].Cells[0].Controls.Add(new LiteralControl("Save Location:"));

            //4,1
            // part 1
            t.Rows[4].Cells[1].Controls.Add(new LiteralControl("Site<br/>"));
            saveLocationSiteDropDownList = new DropDownList();
            saveLocationSiteDropDownList.SelectedIndexChanged += new EventHandler(saveLocationSiteDropDownList_SelectedIndexChanged);
            saveLocationSiteDropDownList.AutoPostBack = true;
            //SPSite oSiteCollection = SPContext.Current.Site;

            //SPWebCollection collWebsite = ArrowUtils.GetSPWebCollectionFromCurrentSite();
            foreach (SPWeb oWebsite in collWebsite)
            {
                saveLocationSiteDropDownList.Items.Add(new ListItem(oWebsite.Title, oWebsite.ID.ToString()));
                oWebsite.Dispose();
            }

            saveLocationSiteDropDownList.SelectedIndex = saveLocationSiteDropDownList.Items.IndexOf(saveLocationSiteDropDownList.Items.FindByValue(SPContext.Current.Web.ID.ToString()));
            t.Rows[4].Cells[1].Controls.Add(saveLocationSiteDropDownList);

            // part 2
            t.Rows[4].Cells[1].Controls.Add(new LiteralControl("<br/><br/>Document Library<br/>"));
            saveLocationLibraryDropDownList = new DropDownList();
            saveLocationLibraryDropDownList.ID = "saveLocationLibDropDownList";
            t.Rows[4].Cells[1].Controls.Add(saveLocationLibraryDropDownList);

            saveLocationSiteDropDownList_SelectedIndexChanged(null, null);

            saveLocationLibDropDownListValidator = new RequiredFieldValidator();
            saveLocationLibDropDownListValidator.Display = ValidatorDisplay.Dynamic;
            saveLocationLibDropDownListValidator.ErrorMessage = "* Select a document library";
            saveLocationLibDropDownListValidator.Text = "* Select a document library";
            saveLocationLibDropDownListValidator.ControlToValidate = "saveLocationLibDropDownList";
            saveLocationLibDropDownListValidator.ValidationGroup = "validationGroup" + this.UniqueID;
            saveLocationLibDropDownListValidator.InitialValue = "";
            t.Rows[4].Cells[1].Controls.Add(saveLocationLibDropDownListValidator);

            return t;
        }
        */
        /// <summary>
        /// Creates datasource selection form.
        /// </summary>
        /// <returns></returns>
        private Table createTable1(Style headerStyle)
        {
            if (log.IsDebugEnabled)
                log.Debug("Creating step 2.");

            ASPxLabel step2Header = new ASPxLabel();
            step2Header.Text = "Step 2: Choose a datasource specification file for each data source found in the template";
            step2Header.ApplyStyle(headerStyle);
            step2Header.Width = Unit.Pixel(700);

            //Table t = createEmptyTable(3, 4, 41, 125);
            int maxNumDataSources = 6;
            Table t = createEmptyTable(3 + maxNumDataSources, 6, 41, 125);

            Style varStyle = new Style();
            varStyle.Font.Name = "Verdana";
            varStyle.Font.Size = FontUnit.Parse("12pt");
            varStyle.Font.Bold = true;

            // labels for each data spec field
            ASPxLabel dataName = new ASPxLabel();
            dataName.Text = "Data Nickname";
            dataName.ApplyStyle(varStyle);
            dataName.Width = Unit.Pixel(200);
            ASPxLabel datasourceSite = new ASPxLabel();
            datasourceSite.Text = "Site";
            datasourceSite.ApplyStyle(varStyle);
            datasourceSite.Width = Unit.Pixel(150);
            ASPxLabel datasourceLib = new ASPxLabel();
            datasourceLib.Text = "Library";
            datasourceLib.ApplyStyle(varStyle);
            datasourceLib.Width = Unit.Pixel(150); ;
            ASPxLabel datasourceFolder = new ASPxLabel();
            datasourceFolder.Text = "Folder";
            datasourceFolder.ApplyStyle(varStyle);
            datasourceFolder.Width = Unit.Pixel(150);
            ASPxLabel fileLabel = new ASPxLabel();
            fileLabel.Text = "File(*.datadef)";
            fileLabel.ApplyStyle(varStyle);
            fileLabel.Width = Unit.Pixel(150);

            Style errorStyle = new Style();
            errorStyle.Font.Name = "Verdana";
            errorStyle.Font.Size = FontUnit.Parse("12pt");
            errorStyle.Font.Bold = true;

            errorMessageLabel2 = new ASPxLabel();
            errorMessageLabel2.Text = "";
            errorMessageLabel2.ClientVisible = false;
            errorMessageLabel2.ApplyStyle(errorStyle);
            errorMessageLabel2.ForeColor = System.Drawing.Color.Red;
           
            // add the labels
            //0,0
            t.Rows[1].Cells[0].Controls.Add(dataName);
            //0,1
            //t.Rows[1].Cells[1].Controls.Add(datasourceLib);
            //0,2
            t.Rows[1].Cells[2].Controls.Add(datasourceSite);
            //0,3
            t.Rows[1].Cells[3].Controls.Add(datasourceLib);
            //0,4
            t.Rows[1].Cells[4].Controls.Add(datasourceFolder);
            //0,5
            t.Rows[1].Cells[5].Controls.Add(fileLabel);

            // arrays of controls for each data spec field
            dataSourceSpecLabelArray = new Label[maxNumDataSources];
            dataSourceSpecSiteDropDownListArray = new DropDownList[maxNumDataSources];
            dataSourceSpecLibraryDropDownListArray = new DropDownList[maxNumDataSources];
            dataSourceSpecFolderDropDownListArray = new DropDownList[maxNumDataSources];
            dataSourceSpecFileDropDownListArray = new DropDownList[maxNumDataSources];

            // instantiate dropdownlistarrays
            for (int i = 0; i < maxNumDataSources; i++)
            {
                // initialize name label
                dataSourceSpecLabelArray[i] = new Label();
                dataSourceSpecLabelArray[i].Visible = false;
                t.Rows[2 + i].Cells[0].Controls.Add(dataSourceSpecLabelArray[i]);

                // initialize list of sites
                dataSourceSpecSiteDropDownListArray[i] = new DropDownList();
                dataSourceSpecSiteDropDownListArray[i].ID = "dataSourceSpecSiteDropDownList" + i.ToString();
                dataSourceSpecSiteDropDownListArray[i].AutoPostBack = true;
                dataSourceSpecSiteDropDownListArray[i].SelectedIndexChanged += new EventHandler(dataSourceSpecSiteDropDownListArray_SelectedIndexChanged);
                dataSourceSpecSiteDropDownListArray[i].Visible = false;
                t.Rows[2 + i].Cells[2].Controls.Add(dataSourceSpecSiteDropDownListArray[i]);

                // initialize list of data def libraries
                dataSourceSpecLibraryDropDownListArray[i] = new DropDownList();
                dataSourceSpecLibraryDropDownListArray[i].ID = "dataSourceSpecLibraryDropDownList" + i.ToString();
                dataSourceSpecLibraryDropDownListArray[i].AutoPostBack = true;
                dataSourceSpecLibraryDropDownListArray[i].SelectedIndexChanged += new EventHandler(dataSourceSpecLibraryDropDownListArray_SelectedIndexChanged);
                dataSourceSpecLibraryDropDownListArray[i].Visible = false;
                t.Rows[2 + i].Cells[3].Controls.Add(dataSourceSpecLibraryDropDownListArray[i]);

                // initialize list of folders
                dataSourceSpecFolderDropDownListArray[i] = new DropDownList();
                dataSourceSpecFolderDropDownListArray[i].ID = "dataSourceSpecFolderDropDownListArray" + i.ToString();
                dataSourceSpecFolderDropDownListArray[i].AutoPostBack = true;
                dataSourceSpecFolderDropDownListArray[i].SelectedIndexChanged += new EventHandler(dataSourceSpecFolderDropDownListArray_SelectedIndexChanged);
                dataSourceSpecFolderDropDownListArray[i].Visible = false;
                t.Rows[2 + i].Cells[4].Controls.Add(dataSourceSpecFolderDropDownListArray[i]);

                // initialize list of data def files
                dataSourceSpecFileDropDownListArray[i] = new DropDownList();
                dataSourceSpecFileDropDownListArray[i].Visible = false;
                t.Rows[2 + i].Cells[5].Controls.Add(dataSourceSpecFileDropDownListArray[i]);
            }

            //IGNORE BELOW NUMBERS
            //1,0
            //1,1
            //1,2
            //2,0
            //Test Button!
            //2,1
            //Label!
            //2,2
            Table container = createEmptyTable(3, 1, 41, 150);
            container.Rows[0].Cells[0].Controls.Add(step2Header);
            container.Rows[1].Cells[0].Controls.Add(errorMessageLabel2);
            container.Rows[2].Cells[0].Controls.Add(t);

            if (log.IsDebugEnabled)
                log.Debug("Finished creating step 2");

            return container;
        }

        void dataSourceSpecFolderDropDownListArray_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (log.IsDebugEnabled)
                log.Debug("handling selected datadef folder changed");
            
            // get index of dropdown list in list array; this has to be done to match it
            // up with the correct file list to update.
            int index = -1;
            for (int i = 0; i < dataSourceSpecFolderDropDownListArray.Length; i++)
            {
                if (sender.Equals(dataSourceSpecFolderDropDownListArray[i]))
                {
                    index = i;
                    break;
                }
            }
            if (index == -1) //bugbug: throw exception?
                return;

            // get the new library
            Guid selSiteID = new Guid(dataSourceSpecSiteDropDownListArray[index].SelectedValue);
            SPWeb site = ArrowUtils.GetSPWebCollectionFromCurrentSite()[selSiteID];
            Guid libraryID = new Guid(dataSourceSpecLibraryDropDownListArray[index].SelectedValue);
            SPDocumentLibrary library = (SPDocumentLibrary)site.Lists[libraryID];
            string sFolderID = dataSourceSpecFolderDropDownListArray[index].SelectedValue;
            SPFolder selFolder = null;
            if (string.IsNullOrEmpty(sFolderID))
                selFolder = library.RootFolder;
            else
            {
                Guid folderID = new Guid(sFolderID);
                selFolder = site.GetFolder(folderID);
            }

            // populate the file list
            dataSourceSpecFileDropDownListArray[index].Items.Clear();
            if (library != null)
            {
                // sort the list items
                ArrayList sortedItems = new ArrayList();
                foreach (SPFile item in selFolder.Files)
                {
                    sortedItems.Add(item);
                }
                sortedItems.Sort(new ArrowUtils.SPFileComparer());

                // add the file items
                foreach (SPFile file in sortedItems)
                {
                    if (file.Name.EndsWith(".datadef") || file.Name.EndsWith(".wrd"))
                    {
                        string dataDefName = string.Empty;
                        if (file.Name.EndsWith(".datadef"))
                            dataDefName = file.Name.Trim().Substring(0, file.Name.Trim().LastIndexOf(".datadef"));
                        else
                            dataDefName = file.Name.Trim().Substring(0, file.Name.Trim().LastIndexOf(".wrd"));
                        dataSourceSpecFileDropDownListArray[index].Items.Add(new ListItem(dataDefName, file.Item.UniqueId.ToString()));
                    }
                }
            }
        }

        void dataSourceSpecSiteDropDownListArray_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (log.IsDebugEnabled)
                log.Debug("handling selected datadef site changed");
            
            // get index of dropdown list in list array; this has to be done to match it
            // up with the correct file list to update.
            int index = -1;
            for (int i = 0; i < dataSourceSpecSiteDropDownListArray.Length; i++)
            {
                if (sender.Equals(dataSourceSpecSiteDropDownListArray[i]))
                {
                    index = i;
                    break;
                }
            }
            if (index == -1) //bugbug: throw exception?
                return;

            // get the selected site
            Guid selSiteID = new Guid(dataSourceSpecSiteDropDownListArray[index].SelectedValue);
            SPWeb selSite = ArrowUtils.GetSPWebCollectionFromCurrentSite()[selSiteID];

            // populate library list
            SPDocumentLibrary library = null;
            bool isFirstLib = true;
            dataSourceSpecLibraryDropDownListArray[index].Items.Clear();
            foreach (SPList list in selSite.Lists)
            {
                if (list is SPDocumentLibrary && !list.Hidden)
                {
                    if (isFirstLib)
                    {
                        library = (SPDocumentLibrary)list;
                        isFirstLib = false;
                    }
                    dataSourceSpecLibraryDropDownListArray[index].Items.Add(new ListItem(list.Title, list.ID.ToString()));
                }
            }

            // populate the folder list
            dataSourceSpecFolderDropDownListArray[index].Items.Clear();
            dataSourceSpecFolderDropDownListArray[index].Items.Add(new ListItem("<None>", ""));
            if (library != null)
            {
                foreach (SPListItem folderItem in library.Folders)
                {
                    SPFolder folder = folderItem.Folder;
                    if (folder != null)
                    {
                        dataSourceSpecFolderDropDownListArray[index].Items.Add(new ListItem(folder.Name, folder.UniqueId.ToString()));
                    }
                }
            }

            // populate the file list
            dataSourceSpecFileDropDownListArray[index].Items.Clear();
            if (library != null)
            {
                SPFolder selFolder = library.RootFolder;

                // sort the list items
                ArrayList sortedItems = new ArrayList();
                foreach (SPFile item in selFolder.Files)
                {
                    sortedItems.Add(item);
                }
                sortedItems.Sort(new ArrowUtils.SPFileComparer());

                // add the file items
                foreach (SPFile file in sortedItems)
                {
                    if (file.Name.EndsWith(".datadef") || file.Name.EndsWith(".wrd"))
                    {
                        string dataDefName = string.Empty;
                        if (file.Name.EndsWith(".datadef"))
                            dataDefName = file.Name.Trim().Substring(0, file.Name.Trim().LastIndexOf(".datadef"));
                        else
                            dataDefName = file.Name.Trim().Substring(0, file.Name.Trim().LastIndexOf(".wrd"));
                        dataSourceSpecFileDropDownListArray[index].Items.Add(new ListItem(dataDefName, file.Item.UniqueId.ToString()));
                    }
                }
            }
        }

        /// <summary>
        /// Creates the parameter definition form.
        /// </summary>
        /// <returns></returns>
        private Table createTable2(Style headerStyle)
        {
            if (log.IsDebugEnabled)
                log.Debug("Creating step 3.");

            ASPxLabel step3Header = new ASPxLabel();
            step3Header.Text = "Step 3: Customize the varible settings.";
            step3Header.ApplyStyle(headerStyle);
            step3Header.Width = Unit.Pixel(700);

            Table t = createEmptyTable(3 + MAX_NUMBER_VARIABLES, 6, 30, 125); // 41 -> 0

            Style varStyle = new Style();
            varStyle.Font.Name = "Verdana";
            varStyle.Font.Size = FontUnit.Parse("12pt");
            varStyle.Font.Bold = true;

            ASPxLabel varName = new ASPxLabel();
            varName.Text = "Variable Name         ";
            varName.ApplyStyle(varStyle);
            varName.Width = Unit.Pixel(200);
            ASPxLabel required = new ASPxLabel();
            required.Text = "Required ?  ";
            required.ApplyStyle(varStyle);
            required.Width = Unit.Pixel(180);
            ASPxLabel hidden = new ASPxLabel();
            hidden.Text = "Hidden ?  ";
            hidden.ApplyStyle(varStyle);
            hidden.Width = Unit.Pixel(160);
            ASPxLabel type = new ASPxLabel();
            type.Text = "Type    ";
            type.ApplyStyle(varStyle);
            type.Width = Unit.Pixel(150);
            ASPxLabel defaultVal = new ASPxLabel();
            defaultVal.Text = "Default Value    ";
            defaultVal.ApplyStyle(varStyle);
            defaultVal.Width = Unit.Pixel(150);
            ASPxLabel descr = new ASPxLabel();
            descr.Text = "Description    ";
            descr.ApplyStyle(varStyle);
            descr.Width = Unit.Pixel(150);

            //0,0
            t.Rows[1].Cells[0].Controls.Add(varName);
            //0,1
            t.Rows[1].Cells[1].Controls.Add(required);
            //0,2
            t.Rows[1].Cells[2].Controls.Add(hidden);
            //0,3
            t.Rows[1].Cells[3].Controls.Add(type);
            //0,4
            t.Rows[1].Cells[4].Controls.Add(defaultVal);
            //0,5
            t.Rows[1].Cells[5].Controls.Add(descr);

            variableNameLabelArray = new Label[MAX_NUMBER_VARIABLES];
            variableRequiredCheckBoxArray = new CheckBox[MAX_NUMBER_VARIABLES];
            variableHiddenCheckBoxArray = new CheckBox[MAX_NUMBER_VARIABLES];
            variableTypeDropDownListArray = new DropDownList[MAX_NUMBER_VARIABLES];
            variableDefaultValueTextBoxArray = new TextBox[MAX_NUMBER_VARIABLES];
            variableDescriptionTextBoxArray = new TextBox[MAX_NUMBER_VARIABLES];

            variableDataNameTextBoxArray = new TextBox[MAX_NUMBER_VARIABLES];
            variableCountTextBoxArray = new TextBox[MAX_NUMBER_VARIABLES];
            variableAllTextBoxArray = new TextBox[MAX_NUMBER_VARIABLES];
            variableValueTextBoxArray = new TextBox[MAX_NUMBER_VARIABLES];
            variableDataNameLiteralControlArray = new Label[MAX_NUMBER_VARIABLES];
            variableCountLabelLiteralControlArray = new Label[MAX_NUMBER_VARIABLES];
            variableAllLabelLiteralControlArray = new Label[MAX_NUMBER_VARIABLES];
            variableValueLabelLiteralControlArray = new Label[MAX_NUMBER_VARIABLES];

            for (int i = 0; i < MAX_NUMBER_VARIABLES; i++)
            {
                variableNameLabelArray[i] = new Label();
                t.Rows[2 + i].Cells[0].Controls.Add(variableNameLabelArray[i]);

                variableRequiredCheckBoxArray[i] = new CheckBox();
                t.Rows[2 + i].Cells[1].Controls.Add(variableRequiredCheckBoxArray[i]);

                variableHiddenCheckBoxArray[i] = new CheckBox();
                t.Rows[2 + i].Cells[2].Controls.Add(variableHiddenCheckBoxArray[i]);

                variableTypeDropDownListArray[i] = new DropDownList();
                variableTypeDropDownListArray[i].Items.Add(new ListItem("Currency", "Currency"));
                variableTypeDropDownListArray[i].Items.Add(new ListItem("Date", "Date"));
                variableTypeDropDownListArray[i].Items.Add(new ListItem("Integer", "Integer"));
                variableTypeDropDownListArray[i].Items.Add(new ListItem("Number", "Number"));
                variableTypeDropDownListArray[i].Items.Add(new ListItem("Select", "Select"));
                variableTypeDropDownListArray[i].Items.Add(new ListItem("Text", "Text"));
                t.Rows[2 + i].Cells[3].Controls.Add(variableTypeDropDownListArray[i]);

                variableDataNameLiteralControlArray[i] = new Label() { Text = "<br/>Data source name<br/>" };
                ////variableDataNameLiteralControlArray[i].Visible = false;
                t.Rows[2 + i].Cells[3].Controls.Add(variableDataNameLiteralControlArray[i]);
                variableDataNameTextBoxArray[i] = new TextBox();
                t.Rows[2 + i].Cells[3].Controls.Add(variableDataNameTextBoxArray[i]);
                variableCountLabelLiteralControlArray[i] = new Label() { Text = "<br/>COUNT(SELECT)<br/>" };
                ////variableCountLabelLiteralControlArray[i].Visible = false;
                t.Rows[2 + i].Cells[3].Controls.Add(variableCountLabelLiteralControlArray[i]);
                variableCountTextBoxArray[i] = new TextBox();
                t.Rows[2 + i].Cells[3].Controls.Add(variableCountTextBoxArray[i]);
                variableAllLabelLiteralControlArray[i] = new Label() { Text = "<br/>SELECT(ALL)<br/>" };
                ////variableAllLabelLiteralControlArray[i].Visible = false;
                t.Rows[2 + i].Cells[3].Controls.Add(variableAllLabelLiteralControlArray[i]);
                variableAllTextBoxArray[i] = new TextBox();
                t.Rows[2 + i].Cells[3].Controls.Add(variableAllTextBoxArray[i]);
                variableValueLabelLiteralControlArray[i] = new Label() { Text = "<br/>SELECT(VALUE)<br/>" };
                ////variableValueLabelLiteralControlArray[i].Visible = false;
                t.Rows[2 + i].Cells[3].Controls.Add(variableValueLabelLiteralControlArray[i]);
                variableValueTextBoxArray[i] = new TextBox();
                t.Rows[2 + i].Cells[3].Controls.Add(variableValueTextBoxArray[i]);

                variableDefaultValueTextBoxArray[i] = new TextBox();
                t.Rows[2 + i].Cells[4].Controls.Add(variableDefaultValueTextBoxArray[i]);

                variableDescriptionTextBoxArray[i] = new TextBox();
                variableDescriptionTextBoxArray[i].TextMode = TextBoxMode.MultiLine;
                t.Rows[2 + i].Cells[5].Controls.Add(variableDescriptionTextBoxArray[i]);
            }
            Table container = createEmptyTable(2, 1, 41, 150);
            container.Rows[0].Cells[0].Controls.Add(step3Header);
            container.Rows[1].Cells[0].Controls.Add(t);

            if (log.IsDebugEnabled)
                log.Debug("Finished creating step 3.");

            return container;
        }
        /*
        private Table createTable3()
        {
            Table t = createEmptyTable(6, 2, 41, 125);
            //0,0

            t.Rows[0].Cells[0].Controls.Add(new LiteralControl("<b>Arrow Report Definition Wizard</b>"));
            t.Rows[0].Cells[1].Controls.Add(new LiteralControl("<u>Summary. Click the Finish Button to create the specified Report Definition File.</u>"));

            //1,0
            t.Rows[1].Cells[0].Controls.Add(new LiteralControl("Title:"));

            //1,1
            titleSummaryLabel = new Label();
            t.Rows[1].Cells[1].Controls.Add(titleSummaryLabel);

            //2,0
            t.Rows[2].Cells[0].Controls.Add(new LiteralControl("Description:"));

            //2,1
            descriptionSummaryLabel = new Label();
            t.Rows[2].Cells[1].Controls.Add(descriptionSummaryLabel);

            //3,0
            t.Rows[3].Cells[0].Controls.Add(new LiteralControl("Location:"));

            //3,1
            locationSummaryLabel = new Label();
            t.Rows[3].Cells[1].Controls.Add(locationSummaryLabel);

            //4,0
            t.Rows[4].Cells[0].Controls.Add(new LiteralControl("Template:"));

            //4,1
            templateSummaryLabel = new Label();
            t.Rows[4].Cells[1].Controls.Add(templateSummaryLabel);

            //5,0 total status
            finalStatusLabel = new Label();
            finalStatusLabel.Text = "Report assembly not created.";
            t.Rows[5].Cells[0].Controls.Add(finalStatusLabel);

            return t;
        }
        */
        #endregion

        #region table creation helper functions

        private Table createEmptyTable(int numRows, int numCols, int rowHeight, int rowWidth)
        {
            Table t = new Table();
            for (int i = 0; i < numRows; i++)
            {
                TableRow r = new TableRow();

                for (int j = 0; j < numCols; j++)
                {
                    TableCell c = new TableCell();
                    c.Height = rowHeight;
                    c.VerticalAlign = VerticalAlign.Top;
                    r.Cells.Add(c);
                }
                r.Width = rowWidth;
                t.Rows.Add(r);
            }
            return t;
        }

        #endregion

        // stolen and modified from template.aspx.cs of Pele
        // get the metrics for the saved temp file template.
        private static TemplateMetrics GetMetrics(string filename)
        {
            //net.windward.api.csharp.Report template = new ReportRtf(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read));
            //template.ProcessSetup();
            TemplateMetrics tm = Report.GetMetrics(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read));
            //template.Close();
            return tm;
        }

        public string getAbsolutePath(Guid siteGuid, Guid docLibGuid, Guid fileGuid)
        {
            return SPContext.Current.Site.MakeFullUrl(getRelativePath(siteGuid, docLibGuid, fileGuid));
        }

        public string getRelativePath(Guid siteGuid, Guid docLibGuid, Guid fileGuid)
        {
            SPWeb site = SPContext.Current.Site.OpenWeb(siteGuid);
            SPDocumentLibrary fileLib = (SPDocumentLibrary)site.Lists[docLibGuid];
            SPFile file = (SPFile)fileLib.Items[fileGuid].File;
            return file.ServerRelativeUrl;
        }
    }
}
